/*
 * Copyright 2020-2030 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/
package com.gitee.minimalismstyle.fresh.simple.service.impl

import com.gitee.minimalismstyle.fresh.common.core.domain.QueryBody
import com.gitee.minimalismstyle.fresh.common.core.domain.QueryParams
import com.gitee.minimalismstyle.fresh.common.core.domain.R
import com.gitee.minimalismstyle.fresh.common.core.domain.Simple
import com.gitee.minimalismstyle.fresh.common.data.beetl.extra.toPageRequest
import com.gitee.minimalismstyle.fresh.common.data.beetl.service.impl.LongModelBaseServiceImpl
import com.gitee.minimalismstyle.fresh.simple.dao.SimpleSqlDao
import com.gitee.minimalismstyle.fresh.simple.api.model.SimpleSql
import com.gitee.minimalismstyle.fresh.simple.api.service.SimpleSqlService
import org.beetl.sql.core.page.PageRequest
import org.beetl.sql.core.page.PageResult
import org.springframework.context.annotation.Primary
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

/**
 * SQL定义业务实现
 * @author maoxiaodong
 */
@Primary
@Service
class SimpleSqlServiceImpl : SimpleSqlService, LongModelBaseServiceImpl<SimpleSqlDao, SimpleSql>() {

    override fun findByCode(code: String): R<SimpleSql> {
        return R.success(dao.findByCode(code))
    }

    override fun findSqlByCode(code: String): R<String> {
        return R.success(dao.findByCode(code).sql)
    }

    override fun executePageById(id: Long, queryParams: QueryParams<Simple>):
            R<QueryBody<Simple>> {
        val simpleSql = dao.findById(id)
        return executePageBySimpleSql(simpleSql, queryParams)
    }

    override fun executePageByCode(
            code: String,
            queryParams: QueryParams<Simple>
    ): R<QueryBody<Simple>> {
        val simpleSql = dao.findByCode(code)
        return executePageBySimpleSql(simpleSql, queryParams)
    }

    override fun executePageBySimpleSql(
            simpleSql: SimpleSql,
            queryParams: QueryParams<Simple>
    ): R<QueryBody<Simple>> {
        val sm = SQLManagerFactoryBean.getObject(simpleSql.datasourceId!!)

        val queryBody: QueryBody<Simple> = QueryBody(totalPage = 1, totalRow = 10)
        if(queryParams.isPage){
            val pageRequest: PageRequest<Simple> = queryParams.toPageRequest()
            val pageResult: PageResult<Simple> = sm.executePageQuery(
                    simpleSql.sql,
                    Simple::class.java,
                    queryParams.params,
                    pageRequest
            )
            queryBody.list = pageResult.list
            queryBody.totalPage = pageResult.totalPage
            queryBody.totalRow = pageResult.totalRow

        }else{
            var sql = simpleSql.sql
            if(queryParams.sort.isNullOrEmpty()){
                sql = "select * from ($sql) order by ${queryParams.sort}"
            }
            val simples = sm.execute(sql,
                    Simple::class.java,
                    queryParams.params)
            queryBody.totalRow = simples.size.toLong()
            queryBody.list = simples
        }

        return R.success(queryBody)
    }


    override fun executeSelectByCode(code: String, params: Simple): R<List<Simple>> {
        val simpleSql = dao.findByCode(code)
        val sm = SQLManagerFactoryBean.getObject(simpleSql.datasourceId!!)
        val simples = sm.execute(simpleSql.sql, Simple::class.java, params)
        return R.success(simples)
    }

    @Transactional
    override fun executeUpdateByCode(code: String, params: Simple): R<Int> {
        val simpleSql = dao.findByCode(code)
        val sm = SQLManagerFactoryBean.getObject(simpleSql.datasourceId!!)
        val n = sm.executeUpdate(simpleSql.sql, params)
        return R.success(n)
    }


}